package com.ruoyi.business.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.bizsys.domain.*;
import com.ruoyi.bizsys.service.*;
import com.ruoyi.business.util.AddressTypeEnum;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ruoyi.business.domain.UnionpayAccount;
import com.ruoyi.business.domain.UnionpayAddress;
import com.ruoyi.business.domain.UnionpayChargebacksFlow;
import com.ruoyi.business.domain.UnionpayCustomer;
import com.ruoyi.business.domain.UnionpayMobile;
import com.ruoyi.business.domain.UnionpayRepaymentPlan;
import com.ruoyi.business.mapper.BCollectionMapper;
import com.ruoyi.business.service.IBZcollectionCustPhoneWarehouseService;
import com.ruoyi.business.service.ICollectionService;
import com.ruoyi.business.util.BathJobMonitorUtil;
import com.ruoyi.bizsys.utils.BizConstants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.service.ISysDictDataService;


/**
 *
 * @author victor
 *
 */
@Slf4j
@Service
public class CollectionServiceImpl implements ICollectionService {

	@Autowired
	private BCollectionMapper collectionMapper;

    @Autowired
    private ICustomerInfoService customerInfoService;

    @Autowired
    private IRealNameAuthService realNameAuthService;

    @Autowired
    private ICreditAccountService creditAccountService;

    @Autowired
    private IAppDeviceInfoService appDeviceInfoService;

    @Autowired
    private ILoanIouService loanIouService;

    @Autowired
    private ILoanOrderService loanOrderService;

    @Autowired
    private IRepaymentOrderService repaymentOrderService;

    @Autowired
    private ICustBankCardService custBankCardService;

    @Autowired
	private ICreditApplyService creditApplyService;

    @Autowired
    private ISysDictDataService sysDictDataService;

    @Autowired
    private IBZcollectionCustPhoneWarehouseService collectionCustPhoneService;

    @Autowired
    private CollectionDBServiceImpl collectionDBServiceImpl;

    @Autowired
	public IZollectionExcludePhoneService iZollectionExcludePhoneService;

    @Autowired
	BathJobMonitorUtil bathJobMonitorUtil;

    @Autowired
	ICustContactsRelativeService iCustContactsRelativeService;

	@Autowired
	IDeviceContactsRelativeService iDeviceContactsRelativeService;

    @Autowired
	IApplyContactsService iApplyContactsService;

	@Autowired
	IDeviceContactsService iDeviceContactsService;

    @Autowired
	RedisCache redisCache;

    @Autowired
	IAppUserService iAppUserService;

    @Autowired
	private IDeviceUserService iDeviceUserService;

	public static String theardName = "CollectionTask";
//	/**
//	 * 催收处理
//	 */
//	@Override
//	public void dealCollection() throws Exception{
//
//		Thread.currentThread().setName(theardName);
//
//		int limitSize = 2000;
//		int pageNo = 0;
//
//		// 删除已有数据
//		collectionDBServiceImpl.delectCollectionInfo();
//
//		String repayDate = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_SLASH, DateUtils.addDays(new Date(), 3));
//
//		// 分页处理逾期客户信息
//		while(true){
//			int startLimit = limitSize * pageNo;
//			List<String> collectCustNos = collectionMapper.getOverdueCustNo(startLimit, limitSize, repayDate);
//
//			if(CollectionUtils.isEmpty(collectCustNos)){
//				break;
//			}
//
//			redisCache.setCacheObject(theardName+BizConstants.MONITOR_COUNTNUMS, redisCache.getCacheObject(theardName+BizConstants.MONITOR_COUNTNUMS)==null?collectCustNos.size():Integer.parseInt(redisCache.getCacheObject(theardName+BizConstants.MONITOR_COUNTNUMS).toString())+collectCustNos.size());
//			log.info("处理第{}页数据，数据量为{}", pageNo + 1, collectCustNos.size());
//
//			for(String overdueCustNo : collectCustNos){
//				try {
//					genCollectionInfo(overdueCustNo);
//				} catch (Exception e) {
//					log.error(overdueCustNo + "入催数据生成异常:", e);
//					bathJobMonitorUtil.setRedis(theardName,"custNo="+collectCustNos,e.getMessage(),"入催数据生成异常");
//				}
//			}
//
//			collectCustNos.clear();
//			pageNo++;
//		}
//	}

	/**
	 * 催收处理
	 */
	@Override
	public void dealCollection(String custNo){

		Thread.currentThread().setName(theardName);

		try {
			genCollectionInfo(custNo);
		} catch (Exception e) {
			log.error(custNo + "入催数据生成异常:", e);
			bathJobMonitorUtil.setRedis(theardName,"custNo="+custNo,e.getMessage(),"入催数据生成异常");
		}
	}

	/**
	 * 生成入催数据
	 * @throws Exception
	 */
	@Override
	public void genCollectionInfo(String collectCustNos) throws Exception{

		log.info("生成入催数据开始:{}", collectCustNos);

		boolean needGetOtherPhone = false;

		// 获取客户信息
		CustomerInfo customerInfoCondition = new CustomerInfo();
		customerInfoCondition.setCustNo(collectCustNos);
		customerInfoCondition.setState(BizConstants.BIZ_STATUS_1);
		List<CustomerInfo> customerInfoList = customerInfoService.selectCustomerInfoList(customerInfoCondition);
		if (CollectionUtils.isEmpty(customerInfoList)) {
        	log.error("未找到客户信息，跳过处理:{}", collectCustNos);
			bathJobMonitorUtil.setRedis(theardName,"custNo="+collectCustNos,"","未找到客户信息");
			return;
		}
		CustomerInfo customerInfo = customerInfoList.get(0);

		// 获取实名信息
		RealNameAuth realNameAuthCondition = new RealNameAuth();
		realNameAuthCondition.setCustNo(collectCustNos);
		realNameAuthCondition.setState(BizConstants.BIZ_STATUS_1);
        List<RealNameAuth> authList = realNameAuthService.selectRealNameAuthList(realNameAuthCondition);
        if (CollectionUtils.isEmpty(authList)) {
        	log.error("未找到实名信息，跳过处理:{}", collectCustNos);
			bathJobMonitorUtil.setRedis(theardName,"custNo="+collectCustNos,"","未找到实名信息");
        	return;
        }
        RealNameAuth realNameAuth = authList.get(0);

        // 获取额度信息
        CreditAccount creditAccountCondition = new CreditAccount();
        creditAccountCondition.setCustNo(collectCustNos);
        creditAccountCondition.setState(BizConstants.BIZ_STATUS_1);
        List<CreditAccount> creditAccountList = creditAccountService.selectCreditAccountList(creditAccountCondition);
        if (CollectionUtils.isEmpty(creditAccountList)) {
        	log.error("未找到额度信息，跳过处理:{}", collectCustNos);
			bathJobMonitorUtil.setRedis(theardName,"custNo="+collectCustNos,"","未找到额度信息");
        	return;
        }
        CreditAccount creditAccount = creditAccountList.get(0);

        // 获取设备信息
        AppDeviceInfo appDeviceInfoCondition = new AppDeviceInfo();
        appDeviceInfoCondition.setUserId(customerInfo.getUserId());
        appDeviceInfoCondition.setState(BizConstants.BIZ_STATUS_0);
        List<AppDeviceInfo> appDeviceInfoList = appDeviceInfoService.selectAppDeviceInfoList(appDeviceInfoCondition);
        if (CollectionUtils.isEmpty(appDeviceInfoList)) {
        	appDeviceInfoList = new ArrayList<AppDeviceInfo>();
        }

        // 获取借据信息
        List<LoanIou> loanIouList = new ArrayList<LoanIou>();
        // 逾期借据
        LoanIou loanIouCondition = new LoanIou();
        loanIouCondition.setCustNo(collectCustNos);
        loanIouCondition.setIouStatus(LoanIou.LOAN_IOU_STATUS_OVERDUE);
        loanIouCondition.setState(BizConstants.BIZ_STATUS_1);
        List<LoanIou> overdueLoanIous = loanIouService.selectLoanIouList(loanIouCondition);
        if (CollectionUtils.isNotEmpty(overdueLoanIous)) {

        	for(LoanIou loan : overdueLoanIous){
        		if(null != loan.getRepayDate()){
        			Date repayDate = DateUtils.parseDate(loan.getRepayDate(), DateUtils.YYYY_MM_DD_SLASH);
        			if(DateUtils.getDaysOfTwoDate(repayDate, new Date()) > 15){
        				needGetOtherPhone = true;
        			}
        		}
        	}

        	loanIouList.addAll(overdueLoanIous);
        	overdueLoanIous.clear();
        }
        // 正常借据
        for(int i = 0; i <= 3; i++){
        	String repayDate = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_SLASH, DateUtils.addDays(new Date(), i));
        	List<LoanIou> normalLoanIous = loanIouService.findNormalLoanIous(collectCustNos, repayDate);
        	if (CollectionUtils.isNotEmpty(normalLoanIous)) {
            	loanIouList.addAll(normalLoanIous);
            	normalLoanIous.clear();
            }
        }

        // 催收数据初始化
        UnionpayCustomer unionpayCustomer = new UnionpayCustomer();
        List<UnionpayAddress> unionpayAddresses = new ArrayList<UnionpayAddress>();
        List<UnionpayMobile> unionpayMobiles = new ArrayList<UnionpayMobile>();
        List<UnionpayAccount> unionpayAccounts = new ArrayList<UnionpayAccount>();
        List<UnionpayRepaymentPlan> unionpayRepaymentPlans = new ArrayList<UnionpayRepaymentPlan>();
        List<UnionpayChargebacksFlow> unionpayChargebacksFlows = new ArrayList<UnionpayChargebacksFlow>();

		CreditApply creditApplyQuery = new CreditApply();
		creditApplyQuery.setCustNo(collectCustNos);
		creditApplyQuery.setState(BizConstants.BIZ_STATUS_1);
		List<CreditApply> creditApplies = creditApplyService.selectCreditApplyList(creditApplyQuery);
		CreditApply creditApply = null;
		if (creditApplies.size() > 0){
			creditApply = creditApplies.get(0);
		}
        // 生成催收用户信息
        genUnionpayCustomer(unionpayCustomer, customerInfo, realNameAuth, creditAccount,creditApply);
        log.info("生成催收用户信息成功:{}", collectCustNos);
        // 生成催收地址信息
        genUnionpayAddresses(unionpayAddresses, realNameAuth, appDeviceInfoList,creditApply);
        log.info("生成催收地址信息成功:{}", collectCustNos);
        // 生成催收联系人信息
        genUnionpayMobiles(unionpayMobiles, creditApply,realNameAuth,needGetOtherPhone);
        log.info("生成催收联系人信息成功:{}", collectCustNos);
        // 生成催收借据相关信息
        genUnionpayLoan(unionpayAccounts, unionpayRepaymentPlans, unionpayChargebacksFlows, realNameAuth, loanIouList, creditAccount);

        // 保存催收数据
        collectionDBServiceImpl.saveCollectionInfo(unionpayCustomer, unionpayAddresses, unionpayMobiles, unionpayAccounts,
				unionpayRepaymentPlans, unionpayChargebacksFlows);

		log.info("生成入催数据结束:{}", collectCustNos);
	}


	@Override
	public void genExcludePhone(){
		List<ZollectionExcludePhone> dataForCallResult = collectionDBServiceImpl.getDataForCallResult();
		List<ZollectionExcludePhone> all = new ArrayList<>();
		all.addAll(dataForCallResult);

		for (int i = 0;i<dataForCallResult.size();i++){
			String phone = dataForCallResult.get(i).getPhone();
			String custNo = dataForCallResult.get(i).getCustNo();

			all.add(new ZollectionExcludePhone("234"+phone.substring(1),custNo));
			all.add(new ZollectionExcludePhone("+234"+phone.substring(1),custNo));
			all.add(new ZollectionExcludePhone("234"+phone,custNo));
			all.add(new ZollectionExcludePhone("+234"+phone,custNo));
		}

		iZollectionExcludePhoneService.saveBatch(all);
	}

	@Override
	public int updateCollectionSmsTaskIsSend() {
		return collectionMapper.updateCollectionSmsTaskIsSend();
	}

	private void genUnionpayLoan(List<UnionpayAccount> unionpayAccounts, List<UnionpayRepaymentPlan> unionpayRepaymentPlans,
			List<UnionpayChargebacksFlow> unionpayChargebacksFlows, RealNameAuth realNameAuth, List<LoanIou> loanIouList,
			CreditAccount creditAccount) throws Exception {

		for(LoanIou loanIou : loanIouList){

			// 排除2021.05.26之前的数据
			Date startCollectDate = DateUtils.parseDate("2021-05-26 00:00:00", DateUtils.YYYY_MM_DD_HH_MM_SS);
			if(loanIou.getCreateTime().before(startCollectDate)){
				continue;
			}

			// 获取还款订单信息
			RepaymentOrder repaymentOrderCondition = new RepaymentOrder();
			repaymentOrderCondition.setLoanSerialNo(loanIou.getLoanSerialNo());
			repaymentOrderCondition.setState(BizConstants.BIZ_STATUS_1);
			repaymentOrderCondition.setRepayStatus(BizConstants.REPAYMENT_ORDER_STATUS_SUCCESS);
			List<RepaymentOrder> repaymentOrderList = repaymentOrderService.selectRepaymentOrderList(repaymentOrderCondition);
			// 获取绑卡信息
			CustBankCard custBankCardCondition = new CustBankCard();
			custBankCardCondition.setCustNo(loanIou.getCustNo());
			custBankCardCondition.setState(BizConstants.BIZ_STATUS_1);
			custBankCardCondition.setIsDefault("Y");
			List<CustBankCard> custBankCardList = custBankCardService.selectCustBankCardList(custBankCardCondition);
			// 获取放款订单信息
			LoanOrder loanOrderCondition = new LoanOrder();
			loanOrderCondition.setLoanSerialNo(loanIou.getLoanSerialNo());
			loanOrderCondition.setState(BizConstants.BIZ_STATUS_1);
			List<LoanOrder> loanOrderList = loanOrderService.selectLoanOrderList(loanOrderCondition);

			// 生成逾期账户信息
			genUnionpayAccount(unionpayAccounts, realNameAuth, loanIou, creditAccount, repaymentOrderList, custBankCardList, loanOrderList);
			log.info("生成催收账户信息成功:{}", loanIou.getLoanSerialNo());

			// 生成逾期还款计划信息
			genUnionpayRepaymentPlan(unionpayRepaymentPlans, loanIou);
			log.info("生成催收还款计划信息成功:{}", loanIou.getLoanSerialNo());

			// 生成扣款流水
			if (CollectionUtils.isNotEmpty(repaymentOrderList)) {
				for(RepaymentOrder repaymentOrder : repaymentOrderList){
					genUnionpayChargebacksFlow(unionpayChargebacksFlows, repaymentOrder, realNameAuth);
				}
			}
			log.info("生成催收扣款流水信息成功:{}", loanIou.getLoanSerialNo());
		}

	}

	private void genUnionpayChargebacksFlow( List<UnionpayChargebacksFlow> unionpayChargebacksFlows,
			RepaymentOrder repaymentOrder, RealNameAuth realNameAuth) throws Exception {
		UnionpayChargebacksFlow unionpayChargebacksFlow = new UnionpayChargebacksFlow();
		unionpayChargebacksFlow.setJobNumber(repaymentOrder.getLoanSerialNo());
		unionpayChargebacksFlow.setTransaction(repaymentOrder.getRepaymentNo());
		unionpayChargebacksFlow.setCustomerName(realNameAuth.getFirstName() + " " + realNameAuth.getLastName());

		if(null != repaymentOrder.getUpdateTime()){
			unionpayChargebacksFlow.setChargebacksDate(Long.parseLong(DateUtils.parseDateToStr(DateUtils.YYYYMMDD, repaymentOrder.getUpdateTime())));
		}
		unionpayChargebacksFlow.setChargebacksAmount(repaymentOrder.getRepaymentAmt());

		// 查询银行卡
		CustBankCard custBankCardCondition = new CustBankCard();
		custBankCardCondition.setCustNo(repaymentOrder.getCustNo());
		custBankCardCondition.setAuthorizationCode(repaymentOrder.getBankCard());
		custBankCardCondition.setState(UserConstants.BUSINESS_NORMAL);
		List<CustBankCard> custBankCards = custBankCardService.selectCustBankCardList(custBankCardCondition);

		CustBankCard custBankCard = null;
		if(CollectionUtils.isNotEmpty(custBankCards)){
			custBankCard = custBankCards.get(0);
		}

		unionpayChargebacksFlow.setBankAccount(null != custBankCard ? custBankCard.getCardNumber() : null);

		unionpayChargebacksFlows.add(unionpayChargebacksFlow);

	}

	private void genUnionpayRepaymentPlan(List<UnionpayRepaymentPlan> unionpayRepaymentPlans, LoanIou loanIou) throws Exception {
		UnionpayRepaymentPlan unionpayRepaymentPlan = new UnionpayRepaymentPlan();
		unionpayRepaymentPlan.setBusJobNumber(loanIou.getLoanSerialNo());
		unionpayRepaymentPlan.setCnJobNumber(loanIou.getLoanSerialNo());
		unionpayRepaymentPlan.setRepaymentPeriod("1");

		if(null != loanIou.getRepayDate()){
			Date repayDate = DateUtils.parseDate(loanIou.getRepayDate(), DateUtils.YYYY_MM_DD_SLASH);
			unionpayRepaymentPlan.setRepaymentDate(Long.parseLong(DateUtils.parseDateToStr(DateUtils.YYYYMMDD, repayDate)));
			unionpayRepaymentPlan.setCostGenerationDate(Long.parseLong(DateUtils.parseDateToStr(DateUtils.YYYYMMDD, repayDate)));
		}

		unionpayRepaymentPlan.setEarlyRepaymentCharge(BigDecimal.ZERO);
		unionpayRepaymentPlan.setSettlementDate(null);
		unionpayRepaymentPlan.setSettlementStatus("N");
		unionpayRepaymentPlan.setPrincipal(loanIou.getLoanPrincipal().subtract(loanIou.getRepaidPrincipal()));
		unionpayRepaymentPlan.setInterest(loanIou.getLoanInterest().subtract(loanIou.getRepaidInterest()));
		unionpayRepaymentPlan.setLateFee(loanIou.getLateFee().subtract(loanIou.getRepaidLateFee()));
		unionpayRepaymentPlan.setServiceFee(loanIou.getServiceFee().subtract(loanIou.getRepaidServiceFee()));
		unionpayRepaymentPlan.setTollCollection(BigDecimal.ZERO);
		unionpayRepaymentPlan.setRecPrincipal(loanIou.getLoanPrincipal().toString());
		unionpayRepaymentPlan.setRecInterest(loanIou.getLoanInterest().toString());
		unionpayRepaymentPlan.setRecOverdueInt(loanIou.getLateFee().toString());
		unionpayRepaymentPlan.setRecServiceFee(loanIou.getServiceFee().toString());
		unionpayRepaymentPlan.setPaidPrincipal(loanIou.getRepaidPrincipal().toString());
		unionpayRepaymentPlan.setPaidInterest(loanIou.getRepaidInterest().toString());
		unionpayRepaymentPlan.setPaidOverdueInt(loanIou.getRepaidLateFee().toString());
		unionpayRepaymentPlan.setPaidServiceFee(loanIou.getRepaidServiceFee().toString());

		unionpayRepaymentPlan.setAdjTotalAmount(loanIou.getFeeRemissionAmt().toString());
		unionpayRepaymentPlan.setShouldAlsoTotal(loanIou.getLoanPrincipal().add(loanIou.getLoanInterest())
				.add(loanIou.getLateFee()).add(loanIou.getServiceFee()));
		unionpayRepaymentPlan.setActualTotalAmount(loanIou.getRepaidPrincipal().add(loanIou.getRepaidInterest())
				.add(loanIou.getRepaidLateFee()).add(loanIou.getRepaidServiceFee()));
		unionpayRepaymentPlan.setOutstdTotalAmount(unionpayRepaymentPlan.getShouldAlsoTotal()
				.subtract(unionpayRepaymentPlan.getActualTotalAmount()).subtract(loanIou.getFeeRemissionAmt()).toString());
		unionpayRepaymentPlan.setSettlementAmount(unionpayRepaymentPlan.getActualTotalAmount());

		unionpayRepaymentPlans.add(unionpayRepaymentPlan);

	}

	private void genUnionpayAccount(List<UnionpayAccount> unionpayAccounts,
			RealNameAuth realNameAuth, LoanIou loanIou, CreditAccount creditAccount,
			List<RepaymentOrder> repaymentOrderList, List<CustBankCard> custBankCardList, List<LoanOrder> loanOrderList) throws Exception {
		BigDecimal totalRec = loanIou.getLoanPrincipal().add(loanIou.getLoanInterest())
				.add(loanIou.getLateFee()).add(loanIou.getServiceFee());
		BigDecimal totalPaid = loanIou.getRepaidPrincipal().add(loanIou.getRepaidInterest())
				.add(loanIou.getRepaidLateFee()).add(loanIou.getRepaidServiceFee());
		BigDecimal totalAdj = loanIou.getFeeRemissionAmt();
		BigDecimal totalOutstd = totalRec.subtract(totalPaid).subtract(totalAdj);

		UnionpayAccount unionpayAccount = new UnionpayAccount();
		unionpayAccount.setAcctnbr(loanIou.getLoanSerialNo());
		unionpayAccount.setAcctcust(realNameAuth.getBvnAccount());
		unionpayAccount.setBusJobNumber(loanIou.getLoanSerialNo());
		if(null != loanIou.getCreateTime()){
			unionpayAccount.setAcctdtopen(Long.parseLong(DateUtils.parseDateToStr(DateUtils.YYYYMMDD, loanIou.getCreateTime())));
			unionpayAccount.setDateLoan(DateUtils.parseDateToStr(DateUtils.YYYYMMDD, loanIou.getCreateTime()));
			unionpayAccount.setGoodsDeliveryTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, loanIou.getCreateTime()));
		}

		if(null != loanIou.getRepayDate()){
			Date repayDate = DateUtils.parseDate(loanIou.getRepayDate(), DateUtils.YYYY_MM_DD_SLASH);
			unionpayAccount.setLoanEndDate(Long.parseLong(DateUtils.parseDateToStr(DateUtils.YYYYMMDD, repayDate)));
			unionpayAccount.setOverdueDate(Long.parseLong(DateUtils.parseDateToStr(DateUtils.YYYYMMDD, repayDate)));
			unionpayAccount.setFirstOverdueDate(repayDate);
			unionpayAccount.setAccountOverdueDays(DateUtils.getDaysOfTwoDate(repayDate, new Date()));
		}

		if(StringUtils.isNotEmpty(loanIou.getDeferredRepayDate())){
			Date deferredRepayDate = DateUtils.parseDate(loanIou.getDeferredRepayDate(), DateUtils.YYYY_MM_DD_SLASH);
			unionpayAccount.setLoanEndDate(Long.parseLong(DateUtils.parseDateToStr(DateUtils.YYYYMMDD, deferredRepayDate)));
			unionpayAccount.setOverdueDate(Long.parseLong(DateUtils.parseDateToStr(DateUtils.YYYYMMDD, deferredRepayDate)));
			unionpayAccount.setAccountOverdueDays(DateUtils.getDaysOfTwoDate(deferredRepayDate, new Date()));
		}

		unionpayAccount.setLoanLimit(null == creditAccount.getCreditLine() ? 0L : creditAccount.getCreditLine().longValue());
		unionpayAccount.setWcsReason("C1");
		unionpayAccount.setAccountSettlementStatus("O");
		if(LoanIou.LOAN_IOU_STATUS_NORMAL == loanIou.getIouStatus()){
			unionpayAccount.setWcsReason("B1");
			unionpayAccount.setAccountSettlementStatus("N");
		}
		unionpayAccount.setProductCode("cash loan");
		unionpayAccount.setProductTypeCode("cash");
		unionpayAccount.setAccountUpdateDate(loanIou.getUpdateTime());
		unionpayAccount.setWcsRepaymentTotalAmount(totalOutstd);
		unionpayAccount.setOverdueBj(loanIou.getLoanPrincipal());
		unionpayAccount.setOverdueLx(loanIou.getLoanInterest());
		unionpayAccount.setOverdueFy(loanIou.getLateFee());
		unionpayAccount.setCollectionCharge(loanIou.getServiceFee());
		unionpayAccount.setEarlyRepaymentCharge(BigDecimal.ZERO);
		unionpayAccount.setPreDepositBalance(BigDecimal.ZERO);
		unionpayAccount.setLoanType("OOP");
		unionpayAccount.setFilingDate(loanIou.getCreateTime());
		unionpayAccount.setFirstPayment(BigDecimal.ZERO);
		unionpayAccount.setNumberPeriodsed(0);
		if (CollectionUtils.isNotEmpty(repaymentOrderList)) {
			unionpayAccount.setLastPayTime(repaymentOrderList.get(0).getUpdateTime());
		}
		if (CollectionUtils.isNotEmpty(custBankCardList)) {
			unionpayAccount.setWithholdAccount(custBankCardList.get(0).getCardNumber());
			unionpayAccount.setCustWithholdingCard(custBankCardList.get(0).getCardNumber());
			unionpayAccount.setCustWithholdingBank(custBankCardList.get(0).getBankName());
		}
		unionpayAccount.setLoanAmount(loanIou.getLoanAmt());
		unionpayAccount.setNumberPeriods(1);
		unionpayAccount.setPayment(totalRec);
		unionpayAccount.setTotalContractNumber(1);
		unionpayAccount.setUnpaidPeriod(totalOutstd);
		unionpayAccount.setTotalAmountDebt(totalOutstd);
		unionpayAccount.setBrand(null);
		unionpayAccount.setProduct(null);
		unionpayAccount.setContractAmount(loanIou.getLoanAmt());
		unionpayAccount.setSurrender(BigDecimal.ZERO);
		unionpayAccount.setPreDeposit(BigDecimal.ZERO);
		unionpayAccount.setForceSettleTag("N");
		unionpayAccount.setLoanTerms(loanIou.getPeriodNum().toString());
		unionpayAccount.setDelayFlag("N");

		int loanRank = collectionMapper.selectLoanSeq(loanIou.getCustNo(), loanIou.getId());
		unionpayAccount.setLoanRank(loanRank);

		// 12-09 调整首贷标志需求
//		取数逻辑，借据表中
//		1）客户首次提现当天若无结清合同，则当天所有合同均为首贷 ，第二天开始的提现为非首贷;
//		2）客户首次提现当天若有结清合同，则当天结清的第1个合同为首贷，第2个合同及以后的合同均为非首贷。
//		unionpayAccount.setReloanFlag(unionpayAccount.getLoanRank() == 1 ? "Y" : "N");
		unionpayAccount.setReloanFlag(isFirstLoan(loanIou, loanRank));
		unionpayAccount.setBankAcctName(realNameAuth.getFirstName() + " " + realNameAuth.getLastName());
		unionpayAccount.setCommodityComment(null);
		unionpayAccount.setEarliestOverdueTerm(1);

		if (CollectionUtils.isNotEmpty(loanOrderList)) {
			unionpayAccount.setBankAcctNo(dstBankAcctNo(loanOrderList.get(0).getAccountNumber()));
		}

		unionpayAccounts.add(unionpayAccount);

	}

	private String isFirstLoan(LoanIou loanIou, int loanRank) {
		String reloanFlag = "Y";
		if(loanRank != 1) {
			// 获取首笔借据
			LoanIou firstLoanIou = collectionMapper.selectFirstLoanIou(loanIou.getCustNo());
			if(DateUtils.isSameDay(loanIou.getCreateTime(), firstLoanIou.getCreateTime())) {
				if(firstLoanIou.getIouStatus() == 1) {
					reloanFlag = "N";
				}
			} else {
				reloanFlag = "N";
			}
		}
		return reloanFlag;
	}

	private String dstBankAcctNo(String bankAcctNo) {
		if(StringUtils.isEmpty(bankAcctNo)){
			return null;
		}

		int length = bankAcctNo.length();
		if(length <= 4){
			return bankAcctNo;
		}

		StringBuffer sbBuffer = new StringBuffer();
		for(int i = 0; i < (length - 4); i++){
			sbBuffer.append("*");
		}
		sbBuffer.append(bankAcctNo.substring(length - 4));

		return sbBuffer.toString();
	}

	private void genUnionpayMobiles(List<UnionpayMobile> unionpayMobiles,CreditApply apply,
			RealNameAuth realNameAuth, boolean needGetOtherPhone){

		log.info("creditApply");
		log.info(apply.toString());
		List<ZcollectionCustPhoneWarehouse> relativePhoneList;

		//获取授信手机号码
		if(null != apply){
			QueryWrapper<CustomerInfo> customerInfoQueryWrapper = new QueryWrapper<>();
			customerInfoQueryWrapper.eq("cust_no",apply.getCustNo()).last("limit 1");
			CustomerInfo one = customerInfoService.getOne(customerInfoQueryWrapper);

			getCreditContact(realNameAuth.getBvnAccount(),one,unionpayMobiles);
		}

		if(needGetOtherPhone){
			//逾期15天外
			//排除剔除号码
			excludeCreditContact(unionpayMobiles);

			//补充10人
			fillContactPhone(realNameAuth.getBvnAccount(),realNameAuth.getUserId(),unionpayMobiles);
		}
	}

	//提取授信联系人
	public void getCreditContact(String bvnAccount,CustomerInfo customerInfo,List<UnionpayMobile> unionpayMobiles){
		UnionpayMobile unionpayMobile1 = new UnionpayMobile();
		unionpayMobile1.setCustrNbr(bvnAccount);
		unionpayMobile1.setConName(customerInfo.getRelateName());
		unionpayMobile1.setConId(null);
		unionpayMobile1.setConTel(customerInfo.getRelatePhone());

		String relation = sysDictDataService.selectDictLabel("relation", customerInfo.getRelation());
		if(StringUtils.isBlank(relation)) {
			relation = customerInfo.getRelation();
		}
		unionpayMobile1.setConRel(relation);
		unionpayMobile1.setEtlDate(null);
		unionpayMobiles.add(unionpayMobile1);

		if(StringUtils.isNotEmpty(customerInfo.getRelatePhone2())){
			String relation2 = sysDictDataService.selectDictLabel("relation2", customerInfo.getRelation2());
			UnionpayMobile unionpayMobile2 = new UnionpayMobile();
			unionpayMobile2.setCustrNbr(bvnAccount);
			unionpayMobile2.setConName(customerInfo.getRelateName2());
			unionpayMobile2.setConId(null);
			unionpayMobile2.setConTel(customerInfo.getRelatePhone2());
			if("Relative".equals(relation2)){
				relation2 = sysDictDataService.selectDictLabel("relation", customerInfo.getRelation2());
				if(StringUtils.isBlank(relation2)) {
					relation2 = customerInfo.getRelation2();
				}
			}else if(StringUtils.isBlank(relation2)){
				relation2 = customerInfo.getRelation2();
			}
			unionpayMobile2.setConRel(relation2);
			unionpayMobile2.setEtlDate(null);
			unionpayMobiles.add(unionpayMobile2);
		}
	}

	//排除授信联系人
	public void excludeCreditContact(List<UnionpayMobile> unionpayMobiles){
		for (int i= 0;i<unionpayMobiles.size();i++){
			QueryWrapper<ZollectionExcludePhone> aollectionExcludePhone = new QueryWrapper<>();
			aollectionExcludePhone.eq("phone",unionpayMobiles.get(i).getConTel());
			int count = iZollectionExcludePhoneService.count(aollectionExcludePhone);
			if(count>0){
				unionpayMobiles.remove(unionpayMobiles.get(i));
				i--;
			}
		}
	}

	//补充10个联系人
	public void fillContactPhone(String bvnAccount,String userId,List<UnionpayMobile> unionpayMobiles){
		if(unionpayMobiles.size() < 10){
			String tableName = iApplyContactsService.getTableName(userId);
			if(StringUtils.isNotBlank(tableName)){
				List<ApplyContacts> list =  iApplyContactsService.getCollectionPhone(tableName,userId,10 - unionpayMobiles.size());
				unionpayMobiles.addAll(buidUnionpayMobileApplyContacts(list,bvnAccount));
			}else{
				List<DeviceContactsRelative> tableNames = iDeviceContactsRelativeService.getTableNamesByUserId(userId);
				List<DeviceContacts> list = iDeviceContactsService.getCollectionPhone(tableNames,userId,10 - unionpayMobiles.size());
				unionpayMobiles.addAll(buidUnionpayMobileDeviceContacts(list,bvnAccount));
			}
		}
	}

	public List<UnionpayMobile> buidUnionpayMobile(List<ZcollectionCustPhoneWarehouse> phoneList,String bvnAccount){

		List<UnionpayMobile> unionpayMobiles = new ArrayList<>();
		if (!CollectionUtils.isEmpty(phoneList)) {
			for(ZcollectionCustPhoneWarehouse collectionCustPhone : phoneList){
				UnionpayMobile unionpayMobile = new UnionpayMobile();
				unionpayMobile.setCustrNbr(bvnAccount);
				unionpayMobile.setConName(collectionCustPhone.getName());
				unionpayMobile.setConId(null);
				unionpayMobile.setConTel(collectionCustPhone.getPhoneNumber());
				unionpayMobile.setConRel(collectionCustPhone.getRelation());
				unionpayMobile.setEtlDate(null);
				unionpayMobiles.add(unionpayMobile);
			}
		}
		return unionpayMobiles;
	}

	public List<UnionpayMobile> buidUnionpayMobileDeviceContacts(List<DeviceContacts> phoneList,String bvnAccount){

		List<UnionpayMobile> unionpayMobiles = new ArrayList<>();
		if (!CollectionUtils.isEmpty(phoneList)) {
			for(DeviceContacts deviceContacts : phoneList){
				UnionpayMobile unionpayMobile = new UnionpayMobile();
				unionpayMobile.setCustrNbr(bvnAccount);
				unionpayMobile.setConName(deviceContacts.getCallName());
				unionpayMobile.setConId(null);
				unionpayMobile.setConTel(deviceContacts.getPhone());
				unionpayMobile.setConRel(deviceContacts.getApplyNo());
				unionpayMobile.setEtlDate(null);
				unionpayMobiles.add(unionpayMobile);
			}
		}
		return unionpayMobiles;
	}

	public List<UnionpayMobile> buidUnionpayMobileApplyContacts(List<ApplyContacts> phoneList,String bvnAccount){

		List<UnionpayMobile> unionpayMobiles = new ArrayList<>();
		if (!CollectionUtils.isEmpty(phoneList)) {
			for(ApplyContacts collectionCustPhone : phoneList){
				UnionpayMobile unionpayMobile = new UnionpayMobile();
				unionpayMobile.setCustrNbr(bvnAccount);
				unionpayMobile.setConName(collectionCustPhone.getCallName());
				unionpayMobile.setConId(null);
				unionpayMobile.setConTel(collectionCustPhone.getPhone());
				unionpayMobile.setConRel(collectionCustPhone.getBatchNo());
				unionpayMobile.setEtlDate(null);
				unionpayMobiles.add(unionpayMobile);
			}
		}
		return unionpayMobiles;
	}


	private void genUnionpayAddresses(List<UnionpayAddress> unionpayAddresses,
			RealNameAuth realNameAuth, List<AppDeviceInfo> appDeviceInfoList,CreditApply apply) {
		for(AppDeviceInfo appDeviceInfo : appDeviceInfoList){
			if(StringUtils.isBlank(appDeviceInfo.getLatitude()) || StringUtils.isBlank(appDeviceInfo.getCountryState())) {
				continue;
			}

			UnionpayAddress unionpayAddress = new UnionpayAddress();

			unionpayAddress.setCustrNbr(realNameAuth.getBvnAccount());
			unionpayAddress.setAddrLine1(appDeviceInfo.getCountryState());
			unionpayAddress.setAddrLine2(appDeviceInfo.getCity());
			unionpayAddress.setAddrLine3(appDeviceInfo.getRegion());
			unionpayAddress.setAddrLine4(appDeviceInfo.getAddress());
//			unionpayAddress.setAddress(appDeviceInfo.getAddress());

			String addressType = appDeviceInfo.getActionType();
			if (StringUtils.equals(addressType, "real_name")) {
				addressType = "Realname";
			} else if (StringUtils.equals(addressType, "apply")) {
				addressType = "Apply";
			} else if (StringUtils.equals(addressType, "loan")) {
				addressType = "Loan";
			}

			unionpayAddress.setAddrType(addressType);
			unionpayAddress.setOseaaddrF("N");

			unionpayAddresses.add(unionpayAddress);
		}
		if (apply != null && StringUtils.isNotBlank(apply.getWorkingAddress())){
			UnionpayAddress unionpayAddress = new UnionpayAddress();
			unionpayAddress.setCustrNbr(realNameAuth.getBvnAccount());

			String workingAddress = apply.getWorkingAddress();
			String[] split = workingAddress.split(",");
			unionpayAddress.setAddrLine1(getIndexValue(split,2));
			unionpayAddress.setAddrLine2(getIndexValue(split,1));
			unionpayAddress.setAddrLine3(getIndexValue(split,0));
//			unionpayAddress.setAddrLine4(getIndexValue(split,3));
//			unionpayAddress.setAddrLine4(apply.getStreet());
			unionpayAddress.setAddrType(AddressTypeEnum.C.getValue());
			unionpayAddress.setOseaaddrF("N");
			if (StringUtils.isNotBlank(apply.getStreet())){
				unionpayAddress.setAddrLine4(apply.getStreet());
			}
			unionpayAddresses.add(unionpayAddress);
		}
	}

	private void genUnionpayCustomer(UnionpayCustomer unionpayCustomer, CustomerInfo customerInfo, RealNameAuth realNameAuth,
			CreditAccount creditAccount,CreditApply apply) throws Exception{
		unionpayCustomer.setCustidnbr(realNameAuth.getBvnAccount());
		unionpayCustomer.setCustidtype("01");
		unionpayCustomer.setCustcstcls("Normal");
		unionpayCustomer.setCustcname(null);
		unionpayCustomer.setCustcrlmtp(null == creditAccount.getCreditLine() ? 0L : creditAccount.getCreditLine().longValue());

		if(null != realNameAuth.getBirthDate()){
			Date birtchDate = DateUtils.parseDate(realNameAuth.getBirthDate(), "dd-MM-yyyy");
			unionpayCustomer.setCustdob(Long.parseLong((DateUtils.parseDateToStr(DateUtils.YYYYMMDD, birtchDate))));
		}

		unionpayCustomer.setCustemail(customerInfo.getEmail());
		unionpayCustomer.setCustsex(realNameAuth.getGender());
		unionpayCustomer.setCustmphone(realNameAuth.getPhoneNumber());
		unionpayCustomer.setCustlname(realNameAuth.getFirstName() + " " + realNameAuth.getLastName());
		if ("Spouses".equals(customerInfo.getRelation())){
			unionpayCustomer.setCustspousename(customerInfo.getRelateName());
		}
		if (apply != null){
			unionpayCustomer.setReligion(sysDictDataService.selectDictLabel("religion", apply.getReligion()));
			unionpayCustomer.setCustannsal(sysDictDataService.selectDictLabel("monthly_income", apply.getMonthlyIncome()));
		}

		QueryWrapper<AppUser> appUserQueryWrapper = new QueryWrapper<>();
		appUserQueryWrapper.eq("user_uuid",realNameAuth.getUserId()).select("phone").last("limit 1");
		AppUser one = iAppUserService.getOne(appUserQueryWrapper);

		unionpayCustomer.setCustrfmblp(customerInfo.getRelatePhone());
		unionpayCustomer.setJbBm(null);
		unionpayCustomer.setFrequencyOfSalaryPaid(null);
		unionpayCustomer.setCustocccode(sysDictDataService.selectDictLabel("industry", customerInfo.getIndustry()));
		unionpayCustomer.setMarriageStatus(sysDictDataService.selectDictLabel("marital_status", customerInfo.getMaritalStatus()));
		unionpayCustomer.setRegisterMobile(one.getPhone());
		unionpayCustomer.setOtherMobile(null);
		unionpayCustomer.setOfflinePaymentCode(null);

	}

	private String getIndexValue(String[] arr, int index){
		try {
			return arr[index];
		} catch (Exception e) {
			return null;
		}
	}

}
